package indigo.ueditor;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;

import com.google.common.collect.Lists;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;

public class UEditorFileManager {

	private final String rootPath;

	public UEditorFileManager(String rootPath) {
		this.rootPath = rootPath;
	}

	public File createFile(String path, InputStream inputStream, long maxSize) {
		File file = Paths.get(rootPath, path).toFile();
		File fileDir = file.getParentFile();
		if (!fileDir.exists() && !fileDir.mkdirs()) {
			throw new UEditorException(UEditorState.FAILED_CREATE_FILE);
		}
		if (!fileDir.canWrite()) {
			throw new UEditorException(UEditorState.PERMISSION_DENIED);
		}

		try {
			try (OutputStream out = new FileOutputStream(file)) {
				ByteStreams.copy(maxSize < 0 ? inputStream : ByteStreams.limit(inputStream, maxSize), out);
			}
			if (inputStream.available() > 0) {
				file.delete();
				throw new UEditorException(UEditorState.MAX_SIZE);
			}
		} catch (IOException e) {
			file.delete();
			throw new UEditorException(UEditorState.IO_ERROR, e);
		}
		return file;
	}

	public List<File> listFiles(String path, Predicate<File> filter) {
		File fileDir = Paths.get(rootPath, path).toFile();
		List<File> list = Lists.newArrayList();
		for (File file : Files.fileTraverser().depthFirstPreOrder(fileDir)) {
			if (!file.isDirectory() && filter.test(file)) {
				list.add(file);
			}
		}
		return Collections.unmodifiableList(list);
	}

	public String getFileUrl(File file) {
		return file.getAbsolutePath()
				.replace(rootPath, rootPath.endsWith("\\") ? "\\" : "")
				.replace('\\', '/');
	}
}
